<script setup lang='ts'>
import {ref, computed, onBeforeMount, watch, nextTick, CSSProperties} from 'vue'
import {tableProps, tableEmits} from './dTable'
import type {ElTable} from 'element-plus'
import {AlignType} from '@/api/config'

const props = defineProps(tableProps)

//表头行内联样式
const headerRowStyle = computed(() => {
  const style:CSSProperties = {}
  style.fontSize = 10 + 'px'
  style.height = props.tableHeadHeight + 'px'
  return style
})

//默认行的样式
const rowStyle = computed(() => {
  const style:CSSProperties = {}
  style.height = props.tableRowHeight + 'px'
  return style
})

//起始index
const baseIndex = computed(() => {
  return (props.pageSize * (props.currentPage - 1))
})

//获取索引
const getItemIndex = (index:number) => {
  return baseIndex.value + index + 1
}

//获取项目索引 没有
const getRowIndex = (row:any):number|undefined => {
  if (!props.tableData) return undefined
  const key = props.rowKey
  for (let i = 0, l = props.tableData.length; i < l; i++) {
    const item = props.tableData[i]
    if (item[key] === row[key]) {
      return i
    }
  }
  return undefined
}

type TableInstance=InstanceType<typeof ElTable>
const dTableRef = ref<TableInstance>()

//设置多选
const setMultipleSelection = (rows:Array<any>) => {
  const dTable = dTableRef.value
  if (dTable) {
    if (rows.length) {
      rows.forEach((row => {
        dTable.toggleRowSelection(row, true)
      }))
    } else {
      dTable.clearSelection()
    }
  }
}


//设置单选
const setSeleted = (row:any) => {
  const dTable = dTableRef.value
  if (dTable) {
    dTable.setCurrentRow(row)
  }
}

//设置滚动
const scrollTo = (top:number|undefined) => {
  const dTable = dTableRef.value
  if (dTable) {
    if (!top) {
      dTable.setScrollTop(0)
    } else {
      //没有超出 TODO 看看el处理了没
      dTable.setScrollTop(top)
    }
  }
}

//滚动到某一项
const scrollToItem = (row:any) => {
  const index = getRowIndex(row)
  const height = index === undefined ? 0 : index * props.tableRowHeight
  scrollTo(height)
}

//监听默认多选和单选
watch(
  () => props.defaultMultipleSelection,
  (defaultMultipleSelection) => {
    setMultipleSelection(defaultMultipleSelection)
  }
)

watch(
  () => props.defaultSeleted,
  (defaultSeleted) => {
    setSeleted(defaultSeleted)
  }
)

//监听滚动
watch(
  () => props.scrollTop,
  (scrollTop) => {
    scrollTo(scrollTop)
  }
)

//监听滚动项
watch(
  () => props.scrollItem,
  (scrollItem) => {
    scrollToItem(scrollItem)
  }
)

//事件
const emits = defineEmits(tableEmits)

//排序改变
const onSortChange = (sort:{column:any, prop:string, order:'ascending'|'descending'}) => {
  emits('sortChange', {prop:sort.prop, order:sort.order})
}

//选中单元格
const onCellClick = (row, col) => {
  emits('cellClick', row, col)
}

//选中
const onRowClick = (row) => {
  emits('rowClick', row)
}

//多选
const onMultipleSelection = (rows:Array<any>) => {
  emits('multipleSelection', rows)
}

//获取输入框对齐方式
const getAlign = (type:AlignType|undefined) => {
  if (type === 'center') {
    return {'d-input-text-center':true}
  }
  else if (type === 'left') {
    return {'d-input-text-left':true}
  }
  else if (type === 'right') {
    return {'d-input-text-right':true}
  } else {
    return {'d-input-text-left':true}
  }
}

// 暴露选择行方法
defineExpose({setSeleted})

onBeforeMount(() => {
  nextTick().then(() => {
    setMultipleSelection(props.defaultMultipleSelection)
    setSeleted(props.defaultSeleted)
  })
})

</script>

<template>
  <div class="d-table-wrapper" :class="{'d-table-wrapper-autoheight':autoHeight,'d-common-flex-full':autoHeight}">
    <el-table
      ref="dTableRef"
      :key="tableRefKey"
      v-loading="showLoading"
      class="d-table-base"
      :height="!autoHeight?'100%':height"
      :max-height="!autoHeight?'100%':maxHeight"
      :data="tableData"
      :stripe="stripe"
      :empty-text="emptyText"
      :highlight-current-row="highlightCurrentRow"
      :border="border"
      :header-row-style="headerRowStyle"
      :row-style="rowStyle"
      :default-sort="defaultSort"
      :row-key="treeConfig?treeConfig.rowKey:undefined"
      :default-expand-all="treeConfig?treeConfig.defaultExpandAll:undefined"
      :lazy="treeConfig?treeConfig.lazy:undefined"
      :load="treeConfig?treeConfig.load:undefined"
      :tree-props="treeConfig?treeConfig.treeProps:undefined"
      :show-summary="showSummary"
      :sum-text="sumText"
      :class="[{'d-table-base-autoheight':autoHeight}]"
      :span-method="spanMethod"
      :row-class-name="rowClassName"
      @sort-change="onSortChange"
      @cell-click="onCellClick"
      @current-change="onRowClick"
      @selection-change="onMultipleSelection"
    >
      <el-table-column v-if="showSelection" type="selection" :width="50" :selectable="selectable" :fixed="true" />
      <el-table-column v-if="showIndex" type="index" width="65" :index="getItemIndex" :fixed="true" label="序号" />
      <el-table-column
        v-for="item in tableHeaderData"
        :key="item.prop"
        :show-overflow-tooltip="item.columnType==='text'"
        :fixed="item.fixed"
        :prop="item.prop"
        :label="item.label"
        :width="item.width"
        :sortable="item.sortable"
        :align="item.align"
        :min-width="item['min-width']"
        :header-align="item['header-align']"
      >
        <template #default="scope">
          <span v-if="item.columnType==='slot'">
            <slot :name="item.prop" :row="scope.row" :item="item" :index="scope.$index" />
          </span>
          <span v-else-if="item.columnType==='text'" class="d-table-col-text">
            {{ scope.row[item.prop] }}
          </span>
          <el-input
            v-else-if="item.columnType==='input'"
            v-model="scope.row[item.prop]"
            :class="[getAlign(item.align)]"
            :placeholder="item.placeholder"
            :disabled="item.disabled"
          />
          <el-input-number
            v-else-if="item.columnType==='inputNumber'"
            v-model="scope.row[item.prop]"
            controls-position="right"
            :class="[getAlign(item.align)]"
            :max="item.max"
            :min="item.min"
            :step-strictly="!item.notStrictly"
            :step="item.step"
            :placeholder="item.placeholder"
            :disabled="item.disabled"
          />
          <el-select
            v-else-if="item.columnType==='selete'"
            v-model="scope.row[item.prop]"
            clearable
            :placeholder="item.placeholder"
            :multiple="item.multiple"
            :collapse-tags="item.multiple"
            :filterable="item.filterable"
            :disabled="item.disabled"
          >
            <el-option v-for="optionItem in item.seleteData" :key="''+optionItem.value" :label="optionItem.label" :value="optionItem.value" />
          </el-select>
        </template>
      </el-table-column>
      <template #append>
        <slot name="append" />
      </template>
    </el-table>
  </div>
</template>

<style scoped>
.d-table-wrapper{
  position: relative;
  height: 100%;
}
.d-table-wrapper-autoheight{
  position: unset;
  height: unset;
}
.d-table-base{
  position: absolute;
  height: 100%;
}
.d-table-base-autoheight{
  position: unset;
  height: unset;
}
.d-table-col-text{
  white-space: nowrap;
  overflow: hidden;
  text-overflow:ellipsis;
}
</style>